/** * 视频上传 公共组件 */
<template>
  <div class="uploadWrapper">
    <vuedraggable
      class="vue-draggable"
      :class="{ single: isSingle, maxHidden: isMaxHidden }"
      v-model="videoList"
      tag="ul"
      draggable=".draggable-item"
      @start="onDragStart"
      @end="onDragEnd"
    >
      <!-- 拖拽元素 -->
      <li
        v-for="(item, index) in videoList"
        :key="item + index"
        class="draggable-item"
        :style="{ width: width + 'px', height: height + 'px' }"
      >
        <video :src="item.url" controls width="720" height="405"></video>
        <!-- <video-player
          class="video-player vjs-custom-skin"
          ref="videoPlayer"
          :playsinline="true"
          :options="playerOptions"
          :z-index="99999"
        ></video-player> -->
        <div class="shadow" @click="onRemoveHandler(index)" v-if="isDelete">
          <i class="el-icon-delete"></i>
        </div>
      </li>
      <!-- 上传按钮 -->
      <el-upload
        slot="footer"
        ref="uploadRef"
        class="uploadBox"
        :style="{ width: width + 'px', height: height + 'px' }"
        :action="action"
        accept=".mp4,.flv,.avi,.wmv,.ogg"
        :show-file-list="false"
        :multiple="!isSingle"
        :limit="limit"
        :before-upload="beforeUpload"
        :on-success="onSuccessUpload"
        :on-exceed="onExceed"
      >
        <i class="el-icon-plus uploadIcon">
          <span class="uploading" v-show="isUploading">正在上传...</span>
          <span>添加视频</span>
          <div class="limitTxt">
            (视频要充分反应图书馆概貌，借阅等场地特色)
          </div>
        </i>
      </el-upload>
    </vuedraggable>
  </div>
</template>

<script>
import vuedraggable from "vuedraggable";

export default {
  name: "videoUpload",

  props: {
    // 图片数据(图片url组成的数组) 通过v-model传递
    // 是否显示删除按钮
    isDelete: {
      type: Boolean,
      default: true,
    },
    value: {
      type: Array,
      default() {
        return [];
      },
    },
    // 限制上传的图片数量
    limit: {
      type: Number,
      default: 99,
    },
    // 限制上传图片的文件大小(kb)
    // 最大上传文件为20M
    size: {
      type: Number,
      default: 1024 * 20,
    },
    // 是否是单图上传(单图上传就是已传图片和上传按钮重叠)
    isSingle: {
      type: Boolean,
      default: false,
    },
    // 视频显示的宽度(px)
    width: {
      type: Number,
      default: 720,
    },
    // 视频显示的高度(px)
    height: {
      type: Number,
      default: 405,
    },
    action: {
      type: String,
      default: "/api/FileUpload/DebtAudit",
    },
    url:{
      type:String
    }
  },

  data() {
    return {
      isUploading: false, // 正在上传状态
      isFirstMount: true, // 控制防止重复回显
      playerOptions: {
        playbackRates: [0.7, 1.0, 1.5, 2.0],   //播放速度
        autoplay: true, 
        muted: false, // 默认消除任何音频
        loop: false, 
        preload: "auto",
        language: "zh-CN",
        aspectRatio: "16:9",
        fluid: true, // 流体 按比例缩放
          sources: [
            {
              type: "video/mp4", 
              src:""
            },
          ],
        // poster: "../../static/images/test.jpg", //封面地址
        // width: document.documentElement.clientWidth, //播放器宽度
        notSupportedMessage: "此视频暂无法播放，请稍后再试", 
        controlBar: {
          timeDivider: true,
          durationDisplay: true,
          remainingTimeDisplay: false,
          fullscreenToggle: true, 
        },
      },
    };
  },

  computed: {
    // 视频数组数据
    videoList: {
      get() {
        return this.value;
      },
      set(val) {
        if (val.length < this.videoList.length) {
          // 判断是删除视频时同步el-upload数据
          this.syncElUpload(val);
        }
        // 同步v-model
        this.$emit("input", val);
      },
    },
    // 控制达到最大限制时隐藏上传按钮
    isMaxHidden() {
      return this.videoList.length >= this.limit;
    },
  },

  watch: {
    value: {
      handler(val) {
        if (this.isFirstMount && this.value.length > 0) {
          this.syncElUpload();
        }

        if (val.length == 0 && this.$refs.uploadRef) {
          this.$refs.uploadRef.clearFiles();
        }
      },
      deep: true,
    },
  },

  mounted() {
    if (this.value.length > 0) {
      this.syncElUpload();
    }
  },

  methods: {
    // 同步el-upload数据
    syncElUpload(val) {
      const videoList = val || this.videoList;

      this.$refs.uploadRef.uploadFiles = videoList.map((v, i) => {
        return {
          name: "pic" + i,
          url: v,
          status: "success",
          // uid: tools.createUniqueString(),
        };
      });
      this.isFirstMount = false;
    },
    // 上传之前
    beforeUpload() {
      this.isFirstMount = false;
      this.isUploading = true;
    },
    // 上传完单张图片
    onSuccessUpload(res, file, fileList) {
      // 这里需要根据你自己的接口返回数据格式和层级来自行修改
      if (res.data.length > 0) {
        // 判断接口上传成功
        this.playerOptions.sources[0].src = res.data[0];
        this.$emit("loadUrl",res.data)
        if (this.videoList.length < this.limit) {
          // 未超限时，把接口返回的图片url地址添加到videoList
          this.videoList.push(res.data[0]);
        }
      } else {
        // 判断接口上传失败
        this.syncElUpload();
        this.$message({ type: "error", message: res.msg });
      }
      this.isUploading = false;
    },
    // 移除单张图片
    onRemoveHandler(index) {
      const _this = this;
      this.$confirm("确定删除该视频?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$emit("deleteVideo")
          let l = _this.videoList.filter((v, i) => {
            return i !== index;
          });
          _this.videoList = l;
        })
        .catch(() => {});
    },
    // 超限
    onExceed() {
      this.$refs.uploadRef.abort(); // 取消剩余接口请求
      this.syncElUpload();
      this.$message({
        type: "warning",
        message: `视频超限`,
      });
    },
    onDragStart(e) {
      e.target.classList.add("hideShadow");
    },
    onDragEnd(e) {
      e.target.classList.remove("hideShadow");
    },
  },

  components: { vuedraggable },
};
</script>

<style lang="scss" scoped>
/deep/ .el-upload {
  width: 100%;
  height: 100%;
}
.video-js .vjs-icon-placeholder {
  width: 100%;
  height: 100%;
  display: block;
}
.vue-draggable {
  padding: 0px;
}

// 上传按钮
.uploadIcon {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  //   border: 1px dashed #c0ccda;
  background-color: #fafafa;
  border-radius: 6px;
  font-size: 20px;
  color: #999;

  .limitTxt,
  .uploading {
    position: absolute;
    bottom: 10%;
    left: 0;
    width: 100%;
    font-size: 14px;
    text-align: center;
  }
  .limitTxt {
    position: absolute;
    bottom: 30%;
    left: 0;
  }
}

// 拖拽
.vue-draggable {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 100%;
  .draggable-item {
    margin-right: 35px;
    margin-bottom: 35px;
    border: 1px solid #ddd;
    border-radius: 6px;
    position: relative;
    overflow: hidden;

    .el-image {
      width: 100%;
      height: 100%;
    }
    .shadow {
      position: absolute;
      top: 0;
      right: 0;
      background-color: rgba(0, 0, 0, 0.5);
      opacity: 0;
      transition: opacity 0.3s;
      color: #fff;
      font-size: 20px;
      line-height: 20px;
      padding: 2px;
      box-sizing: border-box;
      cursor: pointer;
    }
    &:hover {
      .shadow {
        opacity: 1;
      }
    }
  }
  &.hideShadow {
    .shadow {
      display: none;
    }
  }
  &.single {
    overflow: hidden;
    position: relative;

    .draggable-item {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 1;
    }
  }
  &.maxHidden {
    .uploadBox {
      display: none;
    }
  }
}
// el-image
.el-image-viewer__wrapper {
  .el-image-viewer__mask {
    opacity: 0.8;
  }
  .el-icon-circle-close {
    color: #fff;
  }
}
</style>
